﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Media;

namespace SQX.DataModel
{
    public sealed class Service
    {
        public static string GetDescription(Enum value)
        {
            FieldInfo field = value.GetType().GetField(value.ToString());

            DescriptionAttribute attribute
                    = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
                        as DescriptionAttribute;

            return attribute == null ? value.ToString() : attribute.Description;
        }

        public enum SourceType
        {
            [Description("Relational Data Source")]
            SourceSQL = 0,
            [Description("Mutidimensional Data Source")]
            SourceOLAP = 1
        }

        public enum SyntaxTypes
        {
            SyntaxReserved = 0,
            SyntaxFunction = 1,
            SyntaxComment = 2
        }

        public static List<string> IgnoredSymbols = new List<string>() { "{", "}", "(", ")", ";", ":", "]",
                                                                         "0","1","2","3","4","5","6","7","8","9"
                                                                       };

        public static childItem FindVisualChild<childItem>(DependencyObject obj)
                where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }

        public static string GetQueryText(RichTextBox box)
        {
            var range = new TextRange(box.Document.ContentStart, box.Document.ContentEnd);
            return range.Text;
        }

        // syntax coloring method
        public static SolidColorBrush GetSyntaxColor(SyntaxTypes SyntaxType)
        {
            switch (SyntaxType)
            {
                case SyntaxTypes.SyntaxReserved:
                    return new SolidColorBrush(Color.FromRgb(10, 10, 240));
                case SyntaxTypes.SyntaxFunction:
                    return new SolidColorBrush(Color.FromRgb(200, 50, 150));
                case SyntaxTypes.SyntaxComment:
                    return new SolidColorBrush(Colors.DarkGreen);
                default:
                    return new SolidColorBrush(Color.FromRgb(0, 0, 0));
            }
        }

        public static string FindLastWord(RichTextBox box)
        {
            TextPointer current = box.CaretPosition;
            var currentBlock = box.Document.Blocks.Where(x => x.ContentStart.CompareTo(current) == -1 && x.ContentEnd.CompareTo(current) == 1).FirstOrDefault();
            var range = new TextRange(currentBlock.ContentStart, currentBlock.ContentEnd);
            var text = range.Text;
            var index = text.LastIndexOf(' ') + 1;
            return text.Substring(index, text.Length - index).Replace('\r', ' ').Replace('\n', ' ').Trim();
        }

        public static string FindLastWord(TextPointer position)
        {
            string textInRun = position.GetTextInRun(LogicalDirection.Backward);
            return textInRun;
        }

        public static FrameworkElement GetElementFromTabItemTemplate(FrameworkElement container,
                                                                     ItemContainerGenerator containerGenerator,
                                                                     Object Content,
                                                                     string ElementName)
        {
            var item = (DependencyObject)(containerGenerator.ContainerFromItem(Content));
            ContentPresenter itemPresenter = Service.FindVisualChild<ContentPresenter>(container);

            DataTemplate itemDataTemplate = itemPresenter.ContentTemplate;
            return (FrameworkElement)itemDataTemplate.FindName(ElementName, itemPresenter);
        }
    }


    public class ResizeThumb : Thumb
    {
        public ResizeThumb()
        {
            DragDelta += new DragDeltaEventHandler(this.ResizeThumb_DragDelta);
        }

        private void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            Control designerItem = this.DataContext as Control;

            if (designerItem != null)
            {
                double deltaVertical, deltaHorizontal;

                switch (VerticalAlignment)
                {
                    case VerticalAlignment.Bottom:
                        deltaVertical = Math.Min(-e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight);
                        designerItem.Height = designerItem.ActualHeight - deltaVertical;
                        break;
                    case VerticalAlignment.Top:
                        deltaVertical = Math.Min(e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight);
                        Canvas.SetTop(designerItem, Canvas.GetTop(designerItem) + deltaVertical);
                        designerItem.Height -= deltaVertical;
                        break;
                    case VerticalAlignment.Center:
                        break;
                    default:
                        break;
                }

                switch (HorizontalAlignment)
                {
                    case HorizontalAlignment.Left:
                        deltaHorizontal = Math.Min(e.HorizontalChange, designerItem.ActualWidth - designerItem.MinWidth);
                        Canvas.SetLeft(designerItem, Canvas.GetLeft(designerItem) + deltaHorizontal);
                        designerItem.Width -= deltaHorizontal;
                        break;
                    case HorizontalAlignment.Right:
                        deltaHorizontal = Math.Min(-e.HorizontalChange, designerItem.ActualWidth - designerItem.MinWidth);
                        designerItem.Width -= deltaHorizontal;
                        break;
                    case HorizontalAlignment.Center:
                        break;
                    default:
                        break;
                }
            }

            e.Handled = true;
        }
    }
}
